package cn.fatgod.learn.thymeleaf;

import cn.fatgod.learn.thymeleaf.binder.AnnotationDataBinder;
import cn.fatgod.learn.thymeleaf.binder.FieldDataBinder;
import cn.fatgod.learn.thymeleaf.binder.ModelDataBinder;
import cn.fatgod.learn.thymeleaf.binder.PropertyDataBinder;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseResult;
import com.github.javaparser.ast.CompilationUnit;
import com.google.googlejavaformat.java.Formatter;
import com.google.googlejavaformat.java.FormatterException;
import org.junit.jupiter.api.Test;
import org.springframework.util.ResourceUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.StringTemplateResolver;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;

public class Test11 {
    String str = "package cn.fatgod.learn.thymeleaf.template;\n" +
            "\n" +
            "/*[- */\n" +
            "    类路径导入\n" +
            "/* -]*/\n" +
            "[# th:each=\"importPath : ${importPaths}\"]\n" +
            "    import [(${importPath})];\n" +
            "[/]\n" +
            "[# th:if=\"${needSerialize}\"]import java.io.Serializable;[/]\n" +
            "\n" +
            "/*[- */\n" +
            "    类注解\n" +
            "/* -]*/\n" +
            "[# th:each=\"annotation : ${annotations}\"]\n" +
            "@[(${annotation.name})]\n" +
            "    [# th:if = \"${annotation.hasProperty}\"]\n" +
            "        ([# th:each=\"property,ps : ${annotation.properties}\"]\n" +
            "            [# th:if = \"${ps.index} > 0\"],[/]\n" +
            "            [(${property.key})] =\n" +
            "            [# th:if = \"${property.type} == 'STR'\"]\"[(${property.value})]\"[/]\n" +
            "            [# th:if = \"${property.type} == 'TEXT'\"][(${property.value})][/]\n" +
            "        [/])\n" +
            "    [/]\n" +
            "[/]\n" +
            "\n" +
            "/*[- */\n" +
            "    类签名\n" +
            "/* -]*/\n" +
            "[(${modifier})] class [(${name})]\n" +
            "[# th:if = \"${needExtend}\"] extends\n" +
            "    [# th:each=\"extend,es : ${extendList}\"]\n" +
            "        [# th:if = \"${es.index} > 0\"],[/] [(${extend})]\n" +
            "    [/]\n" +
            "[/]\n" +
            "[# th:if = \"${needImpl}\"] implements\n" +
            "    [# th:if=\"${needSerialize}\"] Serializable[/]\n" +
            "    [# th:each=\"impl,is : ${implList}\"]\n" +
            "        [# th:if = \"${is.index} > 0 or ${needSerialize}\"],[/] [(${impl})]\n" +
            "    [/]\n" +
            "[/]\n" +
            "/*[- */\n" +
            "    成员\n" +
            "/* -]*/\n" +
            "{\n" +
            "    [# th:if=\"${needSerialize}\"]private static final long serialVersionUID = 1L;[/]\n" +
            "    [# th:each=\"field : ${fields}\"]\n" +
            "        /*[- */\n" +
            "            字段注解\n" +
            "        /* -]*/\n" +
            "        [# th:each=\"annotation : ${field.annotations}\"]\n" +
            "        @[(${annotation.name})]\n" +
            "            [# th:if = \"${annotation.hasProperty}\"]\n" +
            "                ([# th:each=\"property,ps : ${annotation.properties}\"]\n" +
            "                    [# th:if = \"${ps.index} > 0\"],[/]\n" +
            "                    [(${property.key})] =\n" +
            "                    [# th:if = \"${property.type} == 'STR'\"]\"[(${property.value})]\"[/]\n" +
            "                    [# th:if = \"${property.type} == 'TEXT'\"][(${property.value})][/]\n" +
            "                [/])\n" +
            "            [/]\n" +
            "        [/]\n" +
            "        [(${field.modifier})] [(${field.type})] [(${field.name})];\n" +
            "    [/]\n" +
            "}";

    @Test
    public void test01() {
        Context context = new Context();
        context.setVariable("msg", "msg----");
        Context inn1 = new Context();
        inn1.setVariable("name", "name111----");
        Context inn2 = new Context();
        inn2.setVariable("name", "name222----");
        List<Context> contexts = ListUtil.of(inn1, inn2);
        context.setVariable("inn", contexts);
        String[] arr = new String[]{"name111", "name222"};
        context.setVariable("names", arr);
        StringTemplateResolver stringTemplateResolver = new StringTemplateResolver();
        stringTemplateResolver.setTemplateMode(TemplateMode.TEXT);
        TemplateEngine engine = new TemplateEngine();
//        engine.setDialect(new SpringStandardDialect());
        engine.setTemplateResolver(stringTemplateResolver);
        String process = engine.process("th:text=${names[1]}阿辉sdada", context);
        System.out.println(process);
    }

    public static void main(String[] args) throws IOException, FormatterException {
        StringTemplateResolver stringTemplateResolver = new StringTemplateResolver();
        stringTemplateResolver.setTemplateMode(TemplateMode.TEXT);
        TemplateEngine engine = new TemplateEngine();
        engine.setTemplateResolver(stringTemplateResolver);

        ModelDataBinder model = new ModelDataBinder()
                .setName("test")
                .setNeedSerialize(true);
        AnnotationDataBinder ann1 = new AnnotationDataBinder()
                .setName("Enable")
                .setImportPath("cn.fatgod.Enable")
                .addProp(ListUtil.of(new PropertyDataBinder("value", "ena"), new PropertyDataBinder("name", "test")));
        AnnotationDataBinder ann2 = new AnnotationDataBinder()
                .setName("Perf")
                .setImportPath("cn.fatgod.Perf")
                .addProp(ListUtil.of(new PropertyDataBinder("value", "Text.class", "fatgod.cn.Text")));
        model.addAnnotation(ListUtil.of(ann1, ann2));

        model.addExtend("Object")
                .setNeedSerialize(false)
                .addImpl("Test", "cn.Test")
                .addImpl("Fuck", "cn.Fuck")
                .setNeedSerialize(true);
        FieldDataBinder field = new FieldDataBinder().setName("name")
                .setType("String")
                .addAnnotation(new AnnotationDataBinder().setName("Id")
                        .setImportPath("cn.fg.Id")
                        .addProp(new PropertyDataBinder("value", "注解")));
        model.addField(field);

        Context context = model.bind();
        String process = engine.process(IoUtil.readUtf8(ResourceUtil.getStream("cn/fatgod/learn/thymeleaf/template/asset/ModelTemplate.tpl")), context);
        process = new Formatter().formatSource(process);
        ParseResult<CompilationUnit> parse = new JavaParser().parse(process);
        System.out.println(parse);
        CompilationUnit compilationUnit = parse.getResult().orElse(null);
        System.out.println(compilationUnit);
        IoUtil.write(Files.newOutputStream(ResourceUtils.getFile("Test.java").toPath()), true, process.getBytes(StandardCharsets.UTF_8));
    }
}
